#include "handler.h"
#include <map>

#include "libzq/db/zqmysql.h"
#include "libzq/service/protocol/jrpc.h"
#include "libzqutil/util.h"

using namespace json11;
using namespace jrpc;
using namespace libzq::mysql;

Json::object convert_scheme(const ColumData& row)
{
	Json::object o;
	o["id"] = row["id"];
	o["select"] = row["select_opt"];
	o["bonus_multi"] = row["bonus_multi"];
	o["endline"] = row["endline"];
	auto match_outline = json_load(row["match_outline"]);
	auto loto_outline = json_load(row["loto_outline"]);
	for (auto& it : (Json::object&)match_outline.object_items())
	{
		auto& o_ = (Json::object&)it.second.object_items();
		o_["issue"] = it.first;
		o_["select"] = loto_outline[it.first]["select"];
	}
	o["outline"] = match_outline;
	return std::move(o);
}

response SchemeList::handle(App & app, const request & req)
{
	static auto dbpool = ZQConnPool::create(3, []() -> MysqlConn*
	{
		MysqlConn* conn = new MysqlConn;
		conn->set_config("xxx", "root", "xxx", "xxx", 3306);
		conn->connect();
		return conn;
	}, 3);

	Json::object obj;
	try
	{
		ZQConnHelper conn(dbpool);
		auto query = Query("_lottery_scheme")
			.select("*")
			.right_join(
				Query("_sell_schemes")
				.select("id")
				.on(Table("_lottery_scheme").field("id") = Table("_sell_schemes").field("id"))
			)
			.filter(Field("endline") > current_timestring())
			.exec(conn);
		auto& all_row = query.all_result();
		LOGT(all_row.size());

		Json::array arr_scheme;
		for (auto& row : all_row)
		{
			arr_scheme.emplace_back(convert_scheme(row));
		}
		obj["schemes"] = arr_scheme;
	}
	catch (NoConnError&)
	{

	}
	return response(Json(obj).dump());
}

response SchemeDetail::handle(App & app, const request & req)
{
	static auto dbpool = ZQConnPool::create(3, []() -> MysqlConn*
	{
		MysqlConn* conn = new MysqlConn;
		conn->set_config("xxx", "root", "xxx", "xxx", 3306);
		conn->connect();
		return conn;
	}, 3);
	char* scheme_id = req.url_params.get("scheme_id");
	Json::object obj;
	try
	{
		ZQConnHelper conn(dbpool);
		auto query = Query("_lottery_scheme")
			.select("*")
			.filter(Field("id") = scheme_id)
			.exec(conn);
		auto& row = query.one();
		obj = convert_scheme(row);
	}
	catch (NoResultError& e)
	{
		obj["error"] = 1001;
	}
	catch (NoConnError&)
	{

	}
	return response(Json(obj).dump());
}

response AccountFee::handle(App & app, const request & req)
{
	static auto dbpool = ZQConnPool::create(3, []() -> MysqlConn*
	{
		MysqlConn* conn = new MysqlConn;
		conn->set_config("xxx", "root", "xxx", "xxx", 3306);
		conn->connect();
		return conn;
	}, 10);

	Json::object obj;
	char* phone = req.url_params.get("phone");
	try
	{
		ZQConnHelper conn(dbpool);
		auto query = Query("_user")
			.select("uid")
			.left_join(
				Query("_account")
				.select("balance")
				.on(AND(Table("_account").field("uid") = Table("_user").field("uid"), Field("name") = "ordinary_cash"))
			)
			.filter(Field("phone") = phone)
			.exec(conn);
		auto& row = query.one();
		obj["fee"] = round(CAST_DOUBLE(row["balance"]), 2);
	}
	catch (NoResultError& e)
	{

	}
	catch (NoConnError&)
	{

	}
	return response(Json(obj).dump());
}


response IssueList::handle(App & app, const request & req)
{
	static auto dbpool = ZQConnPool::create(3, []() -> MysqlConn*
	{
		MysqlConn* conn = new MysqlConn;
		conn->set_config("xxx", "root", "xxx", "xxx", 3306);
		conn->connect();
		return conn;
	}, 3);

	Json::object obj;
	try
	{
		ZQConnHelper conn(dbpool);
		auto query = Query("_match")
			.select("*")
			.right_join(
				Query("_lottery_mode")
				.select("lotoid", "single", "curodds", "result")
				.on(Table("_lottery_mode").field("match_id") = Table("_match").field("id"))
			)
			.filter(AND(Field("endline") > current_timestring(), Field("issue") != nullptr))
			.exec(conn);
		auto& all_issue = query.all_result();

		std::map<string, Json::object> issue_map;
		for (auto& issue : all_issue)
		{
			auto& id = issue["id"];
			Json::object& obj_issue = issue_map[id];
			if (obj_issue.empty())
			{
				obj_issue["issue"] = issue["issue"];
				obj_issue["start_at"] = issue["start_at"];
				obj_issue["league"] = issue["league"];
				obj_issue["home"] = issue["home"];
				obj_issue["home_logo"] = issue["home_logo"];
				obj_issue["away"] = issue["away"];
				obj_issue["rq"] = issue["rq"];
				obj_issue["away_logo"] = issue["away_logo"];
				obj_issue["bonuscode"] = issue["bonuscode"];
				obj_issue["cur_score"] = issue["cur_score"];
				obj_issue["cur_delta"] = issue["cur_delta"];
				obj_issue["modes"] = Json::array{};
			}
			Json::object obj_mode;
			obj_mode["lotoid"] = issue["lotoid"];
			obj_mode["single"] = issue["single"];
			obj_mode["curodds"] = issue["curodds"];
			obj_mode["result"] = issue["result"];

			((Json::array&)obj_issue["modes"].array_items()).emplace_back(obj_mode);
		}
		json11::Json::array arr_issue;
		for (auto& issue : issue_map)
		{
			arr_issue.emplace_back(issue.second);
		}
		obj["issues"] = arr_issue;
	}
	catch (NoResultError& e)
	{

	}
	catch (NoConnError&)
	{

	}
	return response(std::move(Json(obj).dump()));
}

response IssueDetail::handle(App & app, const request & req)
{
	static auto dbpool = ZQConnPool::create(3, []() -> MysqlConn*
	{
		MysqlConn* conn = new MysqlConn;
		conn->set_config("xxx", "root", "xxx", "xxx", 3306);
		conn->connect();
		return conn;
	}, 3);
	char* issue_ = req.url_params.get("issue");
	Json::object obj;
	try
	{
		ZQConnHelper conn(dbpool);
		auto query = Query("_match")
			.select("bonuscode")
			.right_join(
				Query("_lottery_mode")
				.select("lotoid", "result")
				.on(Table("_lottery_mode").field("match_id") = Table("_match").field("id"))
			)
			.filter(Field("issue") = issue_)
			.exec(conn);
		auto& all_mode = query.all_result();

		Json::array arr_mode;
		for (auto& mode : all_mode)
		{
			obj["bonuscode"] = mode["bonuscode"];
			arr_mode.emplace_back(Json::object{ {"lotoid", mode["lotoid"]},{"result", mode["result"]} });
		}
		obj["modes"] = arr_mode;
	}
	catch (NoResultError& e)
	{

	}
	catch (NoConnError&)
	{

	}
	return response(std::move(Json(obj).dump()));
}